package com.ruoyi.dataserver.controller;

import cn.hutool.core.util.ObjectUtil;
import com.ruoyi.dataserver.api.dto.PlanningDTO;
import com.ruoyi.dataserver.service.PlanningService;
import com.ruoyi.dataserver.utils.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @ProjectName intelligent-city
 * @Package com.lab.dataserver.controller
 * @ClassName PlanningController
 * @Description TODO
 * @Company lab
 * @Author dongxiang
 * @Date 2020/7/29 16:32
 * @UpdateUser
 * @UpdateDate
 * @UpdateRemark
 * @Version 1.0.0
 */
@RestController
@RequestMapping("/planning")
public class PlanningController {

	@Autowired
	private PlanningService planningService;

	/**
	 * @Title getLinesByDM
	 * @Description 根据类型获取所有管段信息
	 * @param dm
	 * @return com.lab.dataserver.utils.R
	 * @author dongxiang
	 * @date 2020/8/4 11:52
	 * @UpdateUser
	 * @UpdateDate
	 * @UpdateRemark
	 */
	@RequestMapping("/linesByDM")
	public R getLinesByDM(@RequestParam("DM") String dm){
		List lines = planningService.getLines(dm);
		return R.ok(lines);
	}

	/**
	 * @Title getHorizontalBatch
	 * @Description 批量水平距离检测
	 * @param planningDTO
	 * @return com.lab.dataserver.utils.R
	 * @author dongxiang
	 * @date 2020/7/31 14:18
	 * @UpdateUser
	 * @UpdateDate
	 * @UpdateRemark
	 */
	@RequestMapping("/horizontalBatch")
	public R getHorizontalBatch(@RequestBody PlanningDTO planningDTO){
		List res = new ArrayList();
		String[] targetArray = planningDTO.getTarget().split("-");
		Map targetLineInfo = planningService.getLineInfo(targetArray[1],targetArray[0]);
		if (ObjectUtil.isEmpty(targetLineInfo)){
			return R.failed("管线不存在");
		}
		for (String refer :  planningDTO.getRefers()){
			String[] referArray = refer.split("-");
			Map referLineInfo = planningService.getLineInfo(referArray[1],referArray[0]);
			if (ObjectUtil.isEmpty(referLineInfo)){
				return R.failed("管线不存在");
			}
			// 获取实际最短距离
			double distance = planningService.getHorizontalDistance(targetLineInfo.get("SNODID").toString(),targetLineInfo.get("ENODID").toString(),targetLineInfo.get("GJ").toString(),
					referLineInfo.get("SNODID").toString(),referLineInfo.get("ENODID").toString(),referLineInfo.get("GJ").toString());

			// 合法距离
			double legalDistance = planningService.getHorizontalLegalDistance(targetLineInfo.get("DM").toString(),Integer.parseInt(targetLineInfo.get("MSLX").toString()),
					referLineInfo.get("DM").toString(),Integer.parseInt(referLineInfo.get("MSLX").toString()));

			if (distance >= legalDistance) {
				continue;
			}

			Map map = new HashMap();
			map.put("distance",distance);
			map.put("standardDistance",legalDistance);
			map.put("target",planningDTO.getTarget());
			map.put("refer",refer);
			res.add(map);
		}
		return R.ok(res);
	}

	/**
	 * @Title getVerticalBatch
	 * @Description 批量垂直距离检测
	 * @param planningDTO
	 * @return com.lab.dataserver.utils.R
	 * @author dongxiang
	 * @date 2020/7/31 14:18
	 * @UpdateUser
	 * @UpdateDate
	 * @UpdateRemark
	 */
	@RequestMapping("/verticalBatch")
	public R getVerticalBatch(@RequestBody PlanningDTO planningDTO){
		List res = new ArrayList();
		String[] targetArray = planningDTO.getTarget().split("-");
		Map targetLineInfo = planningService.getLineInfo(targetArray[1],targetArray[0]);
		if (ObjectUtil.isEmpty(targetLineInfo)){
			return R.failed("管线不存在");
		}
		for (String refer :  planningDTO.getRefers()){
			String[] referArray = refer.split("-");
			Map referLineInfo = planningService.getLineInfo(referArray[1],referArray[0]);
			if (ObjectUtil.isEmpty(referLineInfo)){
				return R.failed("管线不存在");
			}
			// 获取实际最短距离
			double distance = planningService.getVerticalDistance(new Double(targetLineInfo.get("QDMS").toString()),new Double(targetLineInfo.get("ZDMS").toString()),
					new Double(referLineInfo.get("QDMS").toString()),new Double(referLineInfo.get("ZDMS").toString()));

			// 合法距离
			double legalDistance = planningService.getVerticalLegalDistance(targetLineInfo.get("DM").toString(),Integer.parseInt(targetLineInfo.get("MSLX").toString()),
					referLineInfo.get("DM").toString(),Integer.parseInt(referLineInfo.get("MSLX").toString()));

			if (distance >= legalDistance) {
				continue;
			}

			Map map = new HashMap();
			map.put("distance",distance);
			map.put("standardDistance",legalDistance);
			map.put("target",planningDTO.getTarget());
			map.put("refer",refer);
			res.add(map);
		}
		return R.ok(res);
	}

	/**
	 * @Title minDistance
	 * @Description 获取最小水平和垂直净距(实际),方法参照上方 "/horizontalBatch" 和 "/verticalBatch" 获取最小值
	 * @param planningDTO : 参数
	 * @return com.lab.dataserver.utils.R
	 * @author zgq
	 * @date 2020/8/13 9:45
	 * @UpdateUser
	 * @UpdateDate
	 * @UpdateRemark
	 */
	@RequestMapping("/minDistance")
	public R minDistance(@RequestBody PlanningDTO planningDTO){
		String[] targetArray = planningDTO.getTarget().split("-");
		Map targetLineInfo = planningService.getLineInfo(targetArray[1],targetArray[0]);
		if (ObjectUtil.isEmpty(targetLineInfo)){
			return R.failed("管线不存在");
		}
		//水平和垂直实际净距集合
		List<Double> levelList = new ArrayList<>();
		List<Double> verticalList = new ArrayList<>();
		for (String refer :  planningDTO.getRefers()){
			String[] referArray = refer.split("-");
			Map referLineInfo = planningService.getLineInfo(referArray[1],referArray[0]);
			if (ObjectUtil.isEmpty(referLineInfo)){
				return R.failed("管线不存在");
			}
			// 获取水平实际最短距离
			double levelDistance = planningService.getHorizontalDistance(targetLineInfo.get("SNODID").toString(),targetLineInfo.get("ENODID").toString(),targetLineInfo.get("GJ").toString(),
					referLineInfo.get("SNODID").toString(),referLineInfo.get("ENODID").toString(),referLineInfo.get("GJ").toString());
			levelList.add(levelDistance);
			// 获取垂直实际最短距离
			double verticalDistance = planningService.getVerticalDistance(new Double(targetLineInfo.get("QDMS").toString()),new Double(targetLineInfo.get("ZDMS").toString()),
					new Double(referLineInfo.get("QDMS").toString()),new Double(referLineInfo.get("ZDMS").toString()));
			verticalList.add(verticalDistance);
		}
		//分别获取水平和垂直实际净距最小值并返回(当结果都为0时,最小值=0;当结果除了0以外还有其他值,最小值!=0)
		//先过滤结果为0的数据
		levelList = levelList.stream().filter(min -> min != 0).collect(Collectors.toList());
		verticalList = verticalList.stream().filter(min -> min != 0).collect(Collectors.toList());
		//如果集合为空,则添加0兜底,防止取最小值报错
		if(levelList.isEmpty()){
			levelList.add(0.0);
		}
		if(verticalList.isEmpty()){
			verticalList.add(0.0);
		}
		Map<String,Object> result = new HashMap<>();
		Double minLevel = levelList.stream().mapToDouble(Double::doubleValue).min().getAsDouble();
		Double minVertical = verticalList.stream().mapToDouble(Double::doubleValue).min().getAsDouble();
		result.put("minLevel",minLevel);
		result.put("minVertical",minVertical);
		return R.ok(result);
	}

	/**
	 * @Title getCollisionBatch
	 * @Description 批量碰撞检测
	 * @param planningDTO
	 * @return com.lab.dataserver.utils.R
	 * @author dongxiang
	 * @date 2020/7/31 14:18
	 * @UpdateUser
	 * @UpdateDate
	 * @UpdateRemark
	 */
	@RequestMapping("/collisionBatch")
	public R getCollisionBatch(@RequestBody PlanningDTO planningDTO){
		List res = new ArrayList();
		String[] targetArray = planningDTO.getTarget().split("-");
		Map targetLineInfo = planningService.getLineInfo(targetArray[1],targetArray[0]);
		if (ObjectUtil.isEmpty(targetLineInfo)){
			return R.failed("管线不存在");
		}

		for (String refer :  planningDTO.getRefers()){
			String[] referArray = refer.split("-");
			Map referLineInfo = planningService.getLineInfo(referArray[1],referArray[0]);
			if (ObjectUtil.isEmpty(referLineInfo)){
				return R.failed("管线不存在");
			}
			// 获取水平实际最短距离
			double distanceHorizontal = planningService.getHorizontalDistance(targetLineInfo.get("SNODID").toString(),targetLineInfo.get("ENODID").toString(),targetLineInfo.get("GJ").toString(),
					referLineInfo.get("SNODID").toString(),referLineInfo.get("ENODID").toString(),referLineInfo.get("GJ").toString());

			// 合法水平距离
			double legalDistanceHorizontal = planningService.getHorizontalLegalDistance(targetLineInfo.get("DM").toString(),Integer.parseInt(targetLineInfo.get("MSLX").toString()),
					referLineInfo.get("DM").toString(),Integer.parseInt(referLineInfo.get("MSLX").toString()));

			// 获取垂直实际最短距离
			double distanceVertical = planningService.getVerticalDistance(new Double(targetLineInfo.get("QDMS").toString()),new Double(targetLineInfo.get("ZDMS").toString()),
					new Double(referLineInfo.get("QDMS").toString()),new Double(referLineInfo.get("ZDMS").toString()));

			// 合法垂直距离
			double legalDistanceVertical = planningService.getVerticalLegalDistance(targetLineInfo.get("DM").toString(),Integer.parseInt(targetLineInfo.get("MSLX").toString()),
					referLineInfo.get("DM").toString(),Integer.parseInt(referLineInfo.get("MSLX").toString()));

			// 如果完全合法,跳过
			if (distanceHorizontal >= legalDistanceHorizontal &&
					distanceVertical >= legalDistanceVertical) {
				continue;
			}

			Map map = new HashMap();
			map.put("distanceHorizontal",distanceHorizontal);
			map.put("standardDistanceHorizontal",legalDistanceHorizontal);
			map.put("distanceVertical",distanceVertical);
			map.put("standardDistanceVertical",legalDistanceVertical);
			map.put("target",planningDTO.getTarget());
			map.put("refer",refer);
			res.add(map);
		}
		return R.ok(res);
	}

	@GetMapping("/coverBatch")
	public R coverBatch(@RequestParam(value = "DM")String dm,
						@RequestParam(value = "sid",defaultValue = "0")Integer startId){
		List list = new ArrayList();
		List<Map> lines = new ArrayList();
//		current = (current - 1) > 0 ? current : 1;
		Integer limit = 0;
		Integer condition_size = 100;
		Integer resSize = 10;
		lines = planningService.getLines(dm,startId,limit,condition_size);
		while(list.size() < resSize && !ObjectUtil.isEmpty(lines)){
			for (Map line:lines){
				Map lineInfo = planningService.getLineInfo(line.get("US_ID").toString(),dm);
				if (lineInfo.isEmpty()){
					continue;
				}
				double standardDistance = planningService.getCoverLegalDistance(dm,Integer.parseInt(lineInfo.get("MSLX").toString()));

				// 合规的跳过
				double qdms = 0,zdms = 0;
				if (ObjectUtil.isEmpty(lineInfo.get("QDMS"))){
					qdms = 0;
				}else{
					qdms = Double.parseDouble(lineInfo.get("QDMS").toString());
				}
				if (ObjectUtil.isEmpty(lineInfo.get("ZDMS"))){
					zdms = 0;
				}else {
					zdms = Double.parseDouble(lineInfo.get("ZDMS").toString());
				}
				if (qdms >= standardDistance && zdms >= standardDistance){
					continue;
				}

				Map map = new HashMap();
				map.put("id",lineInfo.get("US_ID").toString());
				map.put("standardDistance",standardDistance);
				map.put("QDMS",lineInfo.get("QDMS").toString());
				map.put("ZDMS",lineInfo.get("ZDMS").toString());
				map.put("US_ID",lineInfo.get("US_ID").toString());
				map.put("SNODID",lineInfo.get("SNODID").toString());
				map.put("ENODID",lineInfo.get("ENODID").toString());
				list.add(map);
				if (list.size() >= resSize){
					break;
				}
			}
			limit = limit + condition_size;
			lines = planningService.getLines(dm,startId,limit,condition_size);
		}
		return R.ok(list);
	}

	/**
	 * @Title getHorizontal
	 * @Description 水平距离检测
	 * @param targetUSID
	 * @param targetDM
	 * @param referUSID
	 * @param referDM
	 * @return com.lab.dataserver.utils.R
	 * @author dongxiang
	 * @date 2020/7/31 14:19
	 * @UpdateUser
	 * @UpdateDate
	 * @UpdateRemark
	 */
	@GetMapping("/horizontal")
	public R getHorizontal(@RequestParam("targetUSID")String targetUSID,@RequestParam("targetDM")String targetDM,
							 @RequestParam("referUSID")String referUSID,@RequestParam("referDM")String referDM){


		Map targetLineInfo = planningService.getLineInfo(targetUSID,targetDM);
		Map referLineInfo = planningService.getLineInfo(referUSID,referDM);

		if (targetLineInfo.isEmpty() || referLineInfo.isEmpty()){
			return R.failed("管线不存在");
		}

		// 获取实际最短距离
		double distance = planningService.getHorizontalDistance(targetLineInfo.get("SNODID").toString(),targetLineInfo.get("ENODID").toString(),targetLineInfo.get("GJ").toString(),
				referLineInfo.get("SNODID").toString(),referLineInfo.get("ENODID").toString(),referLineInfo.get("GJ").toString());

		// 合法距离
		double legalDistance = planningService.getHorizontalLegalDistance(targetLineInfo.get("DM").toString(),Integer.parseInt(targetLineInfo.get("MSLX").toString()),
				referLineInfo.get("DM").toString(),Integer.parseInt(referLineInfo.get("MSLX").toString()));

		Map map = new HashMap();
		map.put("distance",distance);
		map.put("standardDistance",legalDistance);
		return R.ok(map);
	}

	/**
	 * @Title getVertical
	 * @Description 垂直距离检测
	 * @param targetUSID
	 * @param targetDM
	 * @param referUSID
	 * @param referDM
	 * @return com.lab.dataserver.utils.R
	 * @author dongxiang
	 * @date 2020/7/31 14:19
	 * @UpdateUser
	 * @UpdateDate
	 * @UpdateRemark
	 */
	@GetMapping("/vertical")
	public R getVertical(@RequestParam("targetUSID")String targetUSID,@RequestParam("targetDM")String targetDM,
							 @RequestParam("referUSID")String referUSID,@RequestParam("referDM")String referDM){


		Map targetLineInfo = planningService.getLineInfo(targetUSID,targetDM);
		Map referLineInfo = planningService.getLineInfo(referUSID,referDM);

		if (targetLineInfo.isEmpty() || referLineInfo.isEmpty()){
			return R.failed("管线不存在");
		}

		// 获取实际最短距离
		double distance = planningService.getVerticalDistance(new Double(targetLineInfo.get("QDMS").toString()),new Double(targetLineInfo.get("ZDMS").toString()),
				new Double(referLineInfo.get("QDMS").toString()),new Double(referLineInfo.get("ZDMS").toString()));

		// 合法距离
		double legalDistance = planningService.getVerticalLegalDistance(targetLineInfo.get("DM").toString(),Integer.parseInt(targetLineInfo.get("MSLX").toString()),
				referLineInfo.get("DM").toString(),Integer.parseInt(referLineInfo.get("MSLX").toString()));

		Map map = new HashMap();
		map.put("distance",distance);
		map.put("standardDistance",legalDistance);
		return R.ok(map);
	}

	/**
	 * @Title getCover
	 * @Description 覆土检测
	 * @param usid
	 * @param dm
	 * @return com.lab.dataserver.utils.R
	 * @author dongxiang
	 * @date 2020/7/31 14:19
	 * @UpdateUser
	 * @UpdateDate
	 * @UpdateRemark
	 */
	@GetMapping("/cover")
	public R getCover(@RequestParam("USID")String usid,@RequestParam("DM")String dm){

		Map lineInfo = planningService.getLineInfo(usid,dm);
		if (lineInfo.isEmpty()){
			return R.failed("管线不存在");
		}
		double standardDistance = planningService.getCoverLegalDistance(dm,Integer.parseInt(lineInfo.get("MSLX").toString()));

		// 合规的跳过
		double qdms = 0,zdms = 0;
		if (ObjectUtil.isEmpty(lineInfo.get("QDMS"))){
			qdms = 0;
		}else{
			qdms = Double.parseDouble(lineInfo.get("QDMS").toString());
		}
		if (ObjectUtil.isEmpty(lineInfo.get("ZDMS"))){
			zdms = 0;
		}else {
			zdms = Double.parseDouble(lineInfo.get("ZDMS").toString());
		}
		if (qdms >= standardDistance && zdms >= standardDistance){
			return R.ok();
		}

		Map map = new HashMap();
		map.put("standardDistance",standardDistance);
		map.put("QDMS",lineInfo.get("QDMS").toString());
		map.put("ZDMS",lineInfo.get("ZDMS").toString());
		map.put("US_ID",lineInfo.get("US_ID").toString());
		map.put("SNODID",lineInfo.get("SNODID").toString());
		map.put("ENODID",lineInfo.get("ENODID").toString());
		return R.ok(map);
	}

}
